using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Net;
using NUnit.Framework;
using NntpClientLib;

namespace NntpClientLibUnitTests
{
    public static class Rfc977NntpClientWithExtensionsExtensions
    {
        public static void ConnectTest(this Rfc977NntpClientWithExtensions obj)
        {
            var Server = ConfigurationManager.AppSettings["NntpHostname"];
            var UserId = ConfigurationManager.AppSettings["NntpUserIdX"];
            var Password = ConfigurationManager.AppSettings["NntpPassword"];

            obj.Connect(Server);
            // client.AuthenticateUser(UserId, Password);
        }
    }

    [TestFixture]
    public class Rfc977NntpClientWithExtensionsTestFixture
    {
        private string Server = string.Empty;
        private string UserId = string.Empty;
        private string Password = string.Empty;

        [TestFixtureSetUp]
        public void InitializeConfigurationFromAppConfig()
        {
            Server = ConfigurationManager.AppSettings["NntpHostname"];
            UserId = ConfigurationManager.AppSettings["NntpUserId"];
            Password = ConfigurationManager.AppSettings["NntpPassword"];
        }

        [Test]
        public void CheckIfHelpIsImplemented()
        {
            using (var client = new Rfc977NntpClientWithExtensions())
            {
                client.ConnectTest();
                foreach (var s in client.RetrieveHelp())
                {
                    Console.WriteLine(s);
                }
            }
        }

        [Test]
        public void ConstructorAndConfigurationTest()
        {
            using (new Rfc977NntpClientWithExtensions()) { }
        }

        [Test]
        public void GroupSelect()
        {
            using (var client = new Rfc977NntpClientWithExtensions())
            {
                client.ConnectTest();
                client.SendModeReader();
                client.SelectNewsgroup("alt.test");
            }
        }

        [Test]
        public void GroupSelectAndDownloadHeaders()
        {
            using (var client = new Rfc977NntpClientWithExtensions())
            {
                client.ConnectTest();
                client.SendModeReader();
                client.SelectNewsgroup("alt.test");
                foreach (var h in client.RetrieveArticleHeaders())
                {
                    Console.WriteLine(h["Subject"][0]);
                }
            }
        }

        [Test]
        public void GroupSelectAndDownloadMultipleArticles()
        {
            using (var client = new Rfc977NntpClientWithExtensions())
            {
                client.ConnectTest();
                client.SendModeReader();
                client.SelectNewsgroup("alt.test");

                for (var i = 0; i < 2; i++)
                {
                    IArticleHeadersProcessor header = new ArticleHeadersDictionary();
                    IArticleBodyProcessor body = new ArticleBodyTextCollection();
                    client.RetrieveArticle(client.CurrentGroup.FirstArticleId, header, body);
                }
            }
        }

        [Test]
        public void GroupSelectAndDownloadMultipleHeaders()
        {
            using (var client = new Rfc977NntpClientWithExtensions())
            {
                client.ConnectTest();
                client.SendModeReader();
                client.SelectNewsgroup("alt.test");
                Console.WriteLine(client.CurrentGroup.ToString());
                client.ProtocolLogger = Console.Error;
                for (var i = client.CurrentGroup.FirstArticleId; i < client.CurrentGroup.LastArticleId; i++)
                {
                    var header = client.RetrieveArticleHeader();
                    if (i > 10)
                    {
                        break;
                    }
                }
            }
        }

        [Test]
        public void GroupSelectAndDownloadMultipleHeadersUsingArticleId()
        {
            using (var client = new Rfc977NntpClientWithExtensions())
            {
                client.ConnectTest();
                client.SendModeReader();
                client.SelectNewsgroup("alt.test");
                for (var i = client.CurrentGroup.FirstArticleId; i < client.CurrentGroup.LastArticleId; i++)
                {
                    var header = client.RetrieveArticleHeader(i);
                    if (i > 10)
                    {
                        break;
                    }
                }
            }
        }


        [Test]
        public void GroupSelectAndDownloadSingleArticle()
        {
            using (var client = new Rfc977NntpClientWithExtensions())
            {
                client.ConnectTest();
                client.SendModeReader();
                client.SelectNewsgroup("alt.test");

                IArticleHeadersProcessor header = new ArticleHeadersDictionary();
                IArticleBodyProcessor body = new ArticleBodyTextCollection();
                client.RetrieveArticle(client.CurrentGroup.FirstArticleId, header, body);
            }
        }

        [Test]
        public void GroupSelectAndDownloadSingleHeader()
        {
            using (var client = new Rfc977NntpClientWithExtensions())
            {
                client.ConnectTest();
                client.SendModeReader();
                client.SelectNewsgroup("alt.test");
                var header = client.RetrieveArticleHeader();
            }
        }

        [Test]
        public void ListGroups()
        {
            using (var client = new Rfc977NntpClientWithExtensions())
            {
                client.ConnectTest();
                client.SendModeReader();
                foreach (var h in client.RetrieveNewsgroups("alt.*"))
                {
                    Console.WriteLine(h);
                }
            }
        }

        [Test]
        [Explicit]
        public void PostArticleWithAuthentication()
        {
            using (var client = new Rfc977NntpClientWithExtensions())
            {
                client.ConnectTest();

                var newsgroup = "alt.test";
                client.SelectNewsgroup(newsgroup);

                var headers = new ArticleHeadersDictionary();
                headers.AddHeader("From", "anoymous@anon.com (Anonymous)");
                headers.AddHeader("Subject", "Test - " + Guid.NewGuid().ToString());
                headers.AddHeader("Newsgroups", newsgroup);
                headers.AddHeader("Date", new NntpDateTime(DateTime.Now).ToString());

                var body = new List<string>();
                body.Add("One line test message body.");

                client.PostArticle(new ArticleHeadersDictionaryEnumerator(headers), body);
            }
        }

        [Test]
        public void ReadSomeSpecificHeaders()
        {
            using (var client = new Rfc977NntpClientWithExtensions())
            {
                client.ConnectTest();
                client.SendModeReader();
                var newsGroupName = "microsoft.public.dotnet.framework.aspnet";
                client.SelectNewsgroup(newsGroupName);
                Console.WriteLine(client.CurrentGroup);
                foreach (var s in client.RetrieveSpecificArticleHeaders("References", 233887, 373036))
                {
                    //Console.Write("*");
                }
                Console.Out.Flush();
            }
        }

        [Test]
        public void ReadSomeSpecificHeaders2()
        {
            using (var client = new Rfc977NntpClientWithExtensions())
            {
                client.ConnectTest();
                client.SendModeReader();
                var newsGroupName = "alt.test";
                client.SelectNewsgroup(newsGroupName);
                foreach (var s in client.RetrieveSpecificArticleHeaders("References", client.CurrentGroup.FirstArticleId, client.CurrentGroup.LastArticleId))
                {
                    Console.WriteLine(s);
                }
                Console.Out.Flush();
            }
        }

        [Test]
        public void SimpleConnectionTest()
        {
            using (var client = new Rfc977NntpClientWithExtensions())
            {
                client.Connect(Server);
                client.Close();
            }
        }

        [Test]
        [Explicit]
        public void SimpleConnectionTestWithAuthentication()
        {
            using (var client = new Rfc977NntpClientWithExtensions())
            {
                client.Connect(Server);
                client.AuthenticateUser(UserId, Password);
                client.SendModeReader();
            }
        }

        [Test]
        public void SimpleConnectionTestWithModeReader()
        {
            using (var client = new Rfc977NntpClientWithExtensions())
            {
                client.ConnectTest();
                client.SendModeReader();
            }
        }
    }
}